package com.icloud.system.boot.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.BCrypt;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.icloud.auth.api.feign.AuthFeignClient;
import com.icloud.auth.api.vo.Oauth2TokenVo;
import com.icloud.common.cache.util.TokenUtil;
import com.icloud.common.core.api.CommonResult;
import com.icloud.common.core.api.ResultCode;
import com.icloud.common.database.model.AdminUser;
import com.icloud.common.web.domain.UserDto;
import com.icloud.common.web.enums.StateEnum;
import com.icloud.common.web.exception.Asserts;
import com.icloud.common.web.util.AuthUtil;
import com.icloud.system.boot.dao.AdminPermissionDao;
import com.icloud.system.boot.dao.AdminUserDao;
import com.icloud.system.boot.mapper.AdminUserAuthMapper;
import com.icloud.system.boot.model.AdminRole;
import com.icloud.system.boot.model.AdminUserAuth;
import com.icloud.system.boot.service.AdminWhiteListOperationLogService;
import com.icloud.system.boot.service.AdminRoleService;
import com.icloud.system.boot.service.AdminUserAuthService;
import com.icloud.system.boot.service.AdminUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.icloud.common.core.constant.AuthConstant;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 后台账户权限service实现类
 */

@Service
public class AdminUserAuthServiceImpl extends ServiceImpl<AdminUserAuthMapper,AdminUserAuth> implements AdminUserAuthService {

    @Autowired
    private AdminUserService adminUserService;
    @Autowired
    private AdminWhiteListOperationLogService adminWhiteListOperationLogService;
    @Autowired
    private AuthFeignClient authFeignClient;
    @Autowired
    private AdminPermissionDao adminPermissionDao;
    @Autowired
    private AdminUserDao adminUserDao;
    @Autowired
    private AdminRoleService adminRoleService;
    @Autowired
    private AuthUtil authUtil;
    @Autowired
    private TokenUtil tokenUtil;


    /**
     * 后台账号登录
     * @param username 用户名
     * @param password 密码
     */
    @Override
    @Transactional
    public CommonResult<Oauth2TokenVo> adminUserLogin(String username, String password){

        Asserts.fail(StrUtil.isEmpty(username) || StrUtil.isEmpty(password), ResultCode.USERNAME_OR_PASSWORD_CAN_NOT_BE_EMPTY);
        AdminUser adminUser = adminUserService.getOne(new LambdaQueryWrapper<AdminUser>().eq(AdminUser::getUsername, username));
        Asserts.fail(null == adminUser,ResultCode.USERNAME_OR_PASSWORD_ERROR);

        AdminUserAuth adminUserAuth = getOne(new LambdaQueryWrapper<AdminUserAuth>().eq(AdminUserAuth::getAdminUserId, adminUser.getId()));

        //校验密码
        Asserts.fail(!BCrypt.checkpw(password, adminUserAuth.getPassword()),ResultCode.USERNAME_OR_PASSWORD_ERROR);

        //检测账号是否启用
        if(! adminUser.getState().equals(StateEnum.NORMAL.getCode())) {
            Asserts.fail(ResultCode.ACCOUNT_DISABLED);
        }

        //换取token
        Map<String, String> loginParams = new HashMap<>();
        loginParams.put("client_id", AuthConstant.ADMIN_CLIENT_ID);
        loginParams.put("client_secret", AuthConstant.CLIENT_SECRET);
        loginParams.put("grant_type", "password");
        loginParams.put("username", adminUser.getUsername());
        loginParams.put("password", password);
        CommonResult<Oauth2TokenVo> tokenResult = authFeignClient.getAccessToken(loginParams);
        if (ResultCode.SUCCESS.getCode() == tokenResult.getCode() && tokenResult.getData() != null) {
            //获取账号权限信息
            if(null != adminUserAuth.getAdminRoleId()) {
                List<Long> roleIds = null;
                if (adminUserAuth.getAdminRoleId().equals(0L)){
                    List<AdminRole> list = adminRoleService.list();
                    if(CollectionUtil.isNotEmpty(list)){
                        roleIds = list.stream().map(AdminRole::getId).collect(Collectors.toList());
                    }
                }else {
                    roleIds = List.of(adminUserAuth.getAdminRoleId());
                }
                if (CollectionUtil.isNotEmpty(roleIds)){
                    List<String> permissionTags = adminPermissionDao.getPermissionValueByRoleIds(roleIds);
                    //tokenResult.getData().setPermissionTags(permissionTags);
                }
            }
        }else {
        }
        return tokenResult;
    }

    @Override
    public CommonResult<Boolean> adminUserLogout() {
        tokenUtil.removeAccessToken(authUtil.getAuthHashKey());
        return CommonResult.success();
    }


    /**
     * 根据username查询用户信息
     * @param username
     * @return
     */
    @Override
    public UserDto loadUserByUsername(String username) {
        if(StrUtil.isEmpty(username)) {
            return null;
        }
        UserDto userDto = adminUserDao.getUserDto(username);
        //构造数据返回
        userDto.setClientId(AuthConstant.ADMIN_CLIENT_ID);
        //获取账号拥有的角色信息
        AdminUserAuth adminUserAuth = getOne(new LambdaQueryWrapper<AdminUserAuth>().eq(AdminUserAuth::getAdminUserId, userDto.getId()));
        if(null != adminUserAuth.getAdminRoleId()) {
            List<String> roleNameList = null;
            if (adminUserAuth.getAdminRoleId().equals(0L)){
                List<AdminRole> list = adminRoleService.list();
                roleNameList = list.stream().map(role -> AuthConstant.ADMIN_CLIENT_ID + "_" + role.getId() + "_" + role.getName()).collect(Collectors.toList());
            }else {
                AdminRole adminRole = adminRoleService.getById(adminUserAuth.getAdminRoleId());
                if(adminRole!=null) {
                    roleNameList = List.of(AuthConstant.ADMIN_CLIENT_ID + "_" + adminRole.getId() + "_" + adminRole.getName());
                }
            }
            //userDto.setRoles(roleNameList);
        }

        return userDto;
    }


    /**
     * 修改账号登录密码
     */
    @Override
    public void updatePasswordById(Long accountId, String newPassword) {
        //获取账号授权信息
        AdminUserAuth auth = getOne(
                new LambdaQueryWrapper<AdminUserAuth>()
                        .eq(AdminUserAuth::getAdminUserId, accountId)
        );
        if(null == auth) {
            return;
        }
        auth.setPassword(BCrypt.hashpw(newPassword));

        adminUserLogout();

        updateById(auth);
    }
}
